package com.lonely.fx.task;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.NumberFormat;

/**
 * @date: 2022-08-07 12:22
 * @author: ztkj-hzb
 * @description: service 任务类型 属性设置 -- 区别task之处在于可重复使用
 **/
public class ServiceSettingMain extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    /**
     * reset：重置方法，需要在非运行状态才可以执行
     */
    @Override
    public void start(Stage primaryStage) throws Exception {


        HBox hBox = new HBox();

        Button startBtn = new Button("开始");
        Button cancelBtn = new Button("取消");
        Button resetBtn = new Button("重置");
        Button restartBtn = new Button("重启");


        ProgressBar progressBar = new ProgressBar();


        Label progressLbl = new Label("进度值");
        Label statuLbl = new Label("任务状态");
        Label messageLbl = new Label("Message");


        hBox.getChildren().addAll(startBtn, cancelBtn, resetBtn, restartBtn, progressBar, progressLbl, statuLbl, messageLbl);
        hBox.setAlignment(Pos.CENTER);
        hBox.setSpacing(30);
        primaryStage.setScene(new Scene(hBox));
        primaryStage.setWidth(800);
        primaryStage.setHeight(400);
        primaryStage.show();


        MyService myService = new MyService();

        startBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                myService.start();
            }
        });

        cancelBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                myService.cancel();
            }
        });

        resetBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                myService.reset();
            }
        });

        restartBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                myService.restart();
            }
        });


        //监听value变化，设置进度值显示
        myService.valueProperty().addListener(new ChangeListener<Double>() {
            @Override
            public void changed(ObservableValue<? extends Double> observable, Double oldValue, Double newValue) {

                if (newValue == null) {
                    return;
                }

                // 保留小数位数
                NumberFormat nf = NumberFormat.getNumberInstance();
                nf.setMaximumFractionDigits(3);
                String result = nf.format(newValue * 100);

                progressLbl.setText(result + "%");
                progressBar.setProgress(newValue);
            }
        });

        //任务消息监听
        myService.messageProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                messageLbl.setText(newValue);
            }
        });

        //任务状态监听
        myService.stateProperty().addListener(new ChangeListener<Worker.State>() {
            @Override
            public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) {
                statuLbl.setText(newValue.name());

            }
        });


    }
}


class MyService extends Service<Double> {

    /**
     *
     */
    @Override
    protected Task<Double> createTask() {
        Task<Double> task = new Task<Double>() {

            /**
             *
             */
            @Override
            protected Double call() throws Exception {
                InputStream resourceAsStream = this.getClass().getResourceAsStream("/icons/sc01.png");
                int total = resourceAsStream.available();

                FileOutputStream fileOutputStream = new FileOutputStream("D:/test.png");

                double sum = 0;

                byte[] bytes = new byte[50];
                int readCount;

                double currentPropress = 0.0;
                while ((readCount = resourceAsStream.read(bytes)) != -1) {


                    if (this.isCancelled()) {
                        break;
                    }

                    fileOutputStream.write(bytes, 0, readCount);
                    sum += readCount;

                    //回写进度
                    currentPropress = sum / total;
                    this.updateValue(currentPropress);

                    Thread.sleep(50);
                }

                fileOutputStream.close();
                resourceAsStream.close();

                return currentPropress;
            }

            /**
             * 更新值
             */
            @Override
            protected void updateValue(Double value) {
                super.updateValue(value);
                System.out.println("updateValue:" + value);

                if (value >= 0.5 && value < 0.8) {
                    this.updateMessage("任务执行过半");
                } else if (value >= 0.8 && value < 1.0) {
                    this.updateMessage("即将结束");
                } else if (value >= 1) {
                    this.updateMessage("执行完毕");
                } else {
                    this.updateMessage("进行中");
                }

            }
        };
        return task;
    }
}
